#include <algorithm>
#include <iostream>
#include <vector>

void func1() {
    // 传统函数对象
    struct Add {
        int operator()(int a, int b) { return a + b; }
    };
    int x = 666;
    int y = 2;
    // 使用 Lambda 表达式
    auto add = [x,y](int a, int b) { return a + b; };
    std::cout << "add: " << add(x,y) << std::endl;  
}

void func2() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};
    int count = std::count_if(numbers.begin(), numbers.end(), [](int n) { return n % 2 == 0; });
    std::cout << "count: " << count << std::endl;
}

void func3() {
    size_t v1 = 42;
    // 改变捕获的变量值，参数列表上需要加上mutable
    auto f = [v1]() mutable { return ++v1; };
    v1 = 0;
    // std::cout << "f: " << f << std::endl;
    auto j = f();
    std::cout << "j: " << j << std::endl;
}
void func4() {
    size_t v1 = 42;
    // 改变捕获的变量值，参数列表上需要加上mutable
    auto f = [&v1]() { return ++v1; };
    v1 = 0;
    // std::cout << "f: " << f << std::endl;
    auto j = f();
    std::cout << "j: " << j << std::endl;
}
// Here's an explanation of what happens in the code:

// size_t v1 = 42;: This declares and initializes a variable v1 of type size_t with the value 42.

// auto f = [&v1] (){return ++v1;};:
// This creates a lambda function f that captures v1 by reference (&).
// The lambda takes no parameters and returns the value of v1 after incrementing it.
// The mutable keyword is not needed in this case because v1 is already captured by reference,
// allowing it to be modified.

// v1 = 0;: This changes the value of v1 to 0.
// This change will affect the value returned by the lambda function f since it captures v1 by
// reference.

// auto j = f();: This calls the lambda function f and assigns the result to the variable j. Since f
// captures v1 by reference, the modified value of v1 (which is now 0) will be used.

// std::cout << "j: " << j << std::endl;: This prints the value of j to the standard output. In this
// case, it will output "j: 1" because v1 was modified to 0 before calling the lambda function.

// Keep in mind that this code demonstrates the use of lambdas, capturing variables by reference,
// and the mutable keyword. The behavior of capturing variables in lambdas is an important aspect of
// C++ closures, which allows you to create functions that "capture" variables from their
// surrounding context.

void func5()
{ 
int x = 10;
auto func = [x]() { return x * 2; };
int result = func(); // 结果是 20
std::cout << "result: " << result << std::endl;
}

int main() {
    auto f1 = [](int i) { return i = 1; };
    std::cout << f1 << std::endl;
    func1();
    func2();
    func3();
    func4();
    func5();
}